package com.zrkizzy.seckill.consumer;

import com.zrkizzy.seckill.entity.SeckillOrder;
import com.zrkizzy.seckill.entity.User;
import com.zrkizzy.seckill.service.core.IGoodsService;
import com.zrkizzy.seckill.service.core.IOrderService;
import com.zrkizzy.seckill.service.tool.IRedisService;
import com.zrkizzy.seckill.utils.JsonUtil;
import com.zrkizzy.seckill.vo.rabbitmq.SeckillInfoVO;
import com.zrkizzy.seckill.vo.system.GoodsVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static com.zrkizzy.seckill.constant.RabbitMqConst.SECKILL_QUEUE;
import static com.zrkizzy.seckill.constant.RedisConst.ORDER_PREFIX;

/**
 * 秒杀消费者
 *
 * @author zhangrongkang
 * @since 2023/4/8
 */
@Service
@Slf4j
@RabbitListener(queues = SECKILL_QUEUE)
public class SeckillConsumer {
    @Autowired
    private IRedisService redisService;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private IOrderService orderService;

    @RabbitHandler
    public void process(String message) {
        log.info("-------------------------- 消费者开始执行秒杀操作 -------------------------- ");
        log.info("接收到的消息为：{}", message);
        // 将接收到的Json转回为秒杀信息数据对象
        SeckillInfoVO seckillInfoVO = JsonUtil.jsonToObject(message, SeckillInfoVO.class);
        // 获取商品Id和对应用户对象
        Long goodsId = seckillInfoVO.getGoodsId();
        User user = seckillInfoVO.getUser();

        // 获取商品返回数据
        GoodsVO goodsVO = goodsService.getGoodsById(goodsId);
        // 判断库存
        if (goodsVO.getStockCount() < 1) {
            return;
        }
        // 判断是否重复抢购
        SeckillOrder seckillOrder = redisService.get(ORDER_PREFIX + user.getId() + ":" + goodsId, SeckillOrder.class);
        if (null != seckillOrder) {
            log.info("-------------------------- 消费者完成执行秒杀操作 -------------------------- ");
            // 返回重复秒杀结果
            return;
        }

        // 下单操作
        orderService.secKill(user, goodsVO);
        log.info("-------------------------- 消费者完成执行秒杀操作 -------------------------- ");
    }
}
